package com.lost.octopus.es.helper.entity.model;

import com.lost.octopus.es.helper.annotation.EsSearch;
import com.lost.octopus.es.helper.entity.query.PageIn;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.sort.FieldSortBuilder;

import java.util.List;

import lombok.AccessLevel;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.NonNull;
import lombok.Setter;
import lombok.experimental.Accessors;

/**
 * 查询构建对象
 * @author zhangbh
 **/
@Getter
@Setter
@Accessors(chain = true)
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class QueryBuilder {

    /**
     * 分页对象
     */
    private PageIn pageIn;
    /**
     * 查询实体
     */
    private Object data;
    /**
     * 自定义请求参数
     */
    private BoolQueryBuilder queryWrapper;

    /**
     * 默认es查询对象，可对其做扩展操作
     * boolSearch额外支持：高亮
     */
    private SearchSourceBuilder searchBuilder = SearchSourceBuilder.searchSource()
        // 返回命中总数，设置false可以提高效率，但不会返回精确匹配个数
        .trackTotalHits(true);
    /**
     * 自定义排序条件，有则不使用注解解析出来的排序
     */
    private List<FieldSortBuilder> sorts;
    /**
     * 设置false则不进行排序，提高某些情况下（如导出）的性能
     */
    private boolean needSort = true;

    public QueryBuilder(PageIn pageIn, Object data) {
        this.pageIn = pageIn;
        this.data = data;
    }

    /**
     * 快速构建
     * @param currentPage 当前页，从1开始
     * @param pageSize 每页条数
     * @param data 查询对象属性 需要注解{@link EsSearch} 才可解析查询
     * @return 查询对象
     */
    public static QueryBuilder of(int currentPage, int pageSize, Object data) {
        return of(PageIn.of(currentPage, pageSize), data);
    }

    /**
     * 快速构建
     * @param pageIn 分页对象
     * @param data 查询对象属性 需要注解{@link EsSearch} 才可解析查询
     * @return 查询对象
     */
    public static QueryBuilder of(PageIn pageIn, Object data) {
        return new QueryBuilder(pageIn, data);
    }

    /**
     * 快速创建聚合查询条件
     * @param data 查询对象属性 需要注解{@link EsSearch} 才可解析查询
     * @return 查询构建器
     */
    public static QueryBuilder ofAgg(@NonNull Object data) {
        return of(null, data);
    }
}
